package org.ronghao.androidwifiplatfrom.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.ronghao.androidwifiplatfrom.entity.User;
import org.ronghao.androidwifiplatfrom.entity.WifiAPInfo;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.DhcpInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.text.format.Formatter;

public class Wifi {
	private WifiManager mWifiManager;// 本地WIFI设置
	private WifiInfo mWifiInfo; // 当前WIFI连接信息
	private List<ScanResult> mWifiList; // 扫描出的周围网络连接列表
	private List<WifiConfiguration> mWifiConfigurationList; // 保存过的网络连接列表
	private WifiLock mWifiLock;// Wifi锁
	private DhcpInfo dhcpInfo;
	private String serverIP = "127.0.0.1";// 主机IP地址
	private User mLocalUser;// 本机User
	private List<User> mUsers = new ArrayList<User>();
	private SharedPreferences sp;

	public static final int WIFI_AP_STATE_DISABLING = 10;
	public static final int WIFI_AP_STATE_DISABLED = 11;
	public static final int WIFI_AP_STATE_ENABLING = 12;
	public static final int WIFI_AP_STATE_ENABLED = 13;
	public static final int WIFI_AP_STATE_FAILED = 14;

	private static Wifi instance;
	// private static Context mContext;

	private static Object INSTANCE_LOCK = new Object();

	/**
	 * 单例模式
	 * 
	 * @author ronghao
	 * @data 2012-11-14 下午4:00:54
	 * @param context
	 * @return
	 */
	public static Wifi getInstance(Context context) {

		if (instance == null) {
			synchronized (INSTANCE_LOCK) {
				instance = new Wifi(context);
				// mContext = context;
			}
		}
		return instance;
	}

	/**
	 * 退出
	 * 
	 * @author ronghao
	 * @data 2012-11-28 上午9:29:46
	 */
	public void exit() {
		reset();
		instance = null;
		mUsers = null;
		mLocalUser = null;
	}

	/**
	 * 
	 * @author ronghao
	 * @data 2012-11-28 下午6:49:52
	 * @param mWifiInfo
	 */
	public void setmWifiInfo(WifiInfo mWifiInfo) {
		this.mWifiInfo = mWifiInfo;
	}

	/**
	 * 重置信息
	 * 
	 * @author ronghao
	 * @data 2012-11-28 上午9:27:40
	 */
	public void reset() {
		Editor editor = sp.edit();
		editor.putString(Contants.COMMUNICATION_USER_IP, "127.0.0.1");
		editor.commit();
		if (getWifiState()) {
			closeWifi();
		}
		if (getAPState()) {
			closeWifiAP();
		}
	}

	public Wifi(Context context) {
		mWifiManager = (WifiManager) context
				.getSystemService(Context.WIFI_SERVICE);
		mWifiInfo = mWifiManager.getConnectionInfo();

		mLocalUser = new User();
		sp = context.getSharedPreferences(Contants.APP_LOCATION_SET,
				Context.MODE_WORLD_READABLE);
		setLocalUser();
		// SharedPreferences sp =
		// context.getSharedPreferences(Contants.APP_LOCATION_SET,
		// Context.MODE_WORLD_READABLE);
		// mLocalUser.setName(sp.getString(Contants.COMMUNICATION_USER_NAME,
		// "0"));
		// mLocalUser.setPic(sp.getInt(Contants.COMMUNICATION_USER_PIC, 0));
		// mLocalUser.setStyle(sp.getInt(Contants.COMMUNICATION_USER_STYLE, 0));
		// mLocalUser.setIp(sp.getString(Contants.COMMUNICATION_USER_IP,
		// "127.0.0.1"));

	}

	/**
	 * wifi状态
	 * 
	 * @author ronghao
	 * @data 2012-11-21 下午1:02:17
	 * @return
	 */
	public Boolean getWifiState() {
		return mWifiManager.isWifiEnabled();
	}

	/**
	 * 获得网关
	 * 
	 * @author ronghao
	 * @return
	 * @data 2012-11-14 下午8:00:17
	 */
	public String getDHCPIP() {
		dhcpInfo = mWifiManager.getDhcpInfo();
		String string = Formatter.formatIpAddress(dhcpInfo.gateway);
		if (string.contains("192.168.1")) {
			return serverIP;
		}
		// if (serverIP == null) {
		// serverIP = string;
		// }
		return string;
	}

	/**
	 * 打开WIFI
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午10:59:58
	 */
	public void openWifi() {
		if (!mWifiManager.isWifiEnabled()) {
			mWifiManager.setWifiEnabled(true);
		}
	}

	/**
	 * 关闭WIFI
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午11:00:35
	 */
	public void closeWifi() {
		if (mWifiManager.isWifiEnabled()) {
			mWifiManager.setWifiEnabled(false);
		}
	}

	/**
	 * 检查当前WIFI状态
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午11:00:46
	 * @return
	 */
	public Boolean checkState() {
		if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED
				&& mWifiManager.getConnectionInfo().getIpAddress() != 0) {
			setmWifiInfo(mWifiManager.getConnectionInfo());
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 获得AP的状态
	 * 
	 * @author ronghao
	 * @data 2012-11-28 下午7:11:47
	 * @return
	 */
	public Boolean getAPState() {

		Method method;
		try {
			method = mWifiManager.getClass().getMethod("getWifiApState");
			method.invoke(mWifiManager);
			mWifiManager.getConnectionInfo();
			return (Integer) method.invoke(mWifiManager) == WIFI_AP_STATE_ENABLED
					&& !(mWifiManager.getConnectionInfo().getSupplicantState()
							.equals("COMPLETED"));
		} catch (SecurityException e) {
			e.printStackTrace();
			return false;
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
			return false;
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
			return false;
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			return false;
		} catch (InvocationTargetException e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 创建一个WIFILock
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午11:01:16
	 */
	public void createWifiLock() {
		mWifiLock = mWifiManager.createWifiLock("test");
	}

	/**
	 * 锁定WIFILock
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午11:01:00
	 */
	public void acquireWifiLock() {
		mWifiLock.acquire();
	}

	/**
	 * 解锁WIFILock
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午11:01:06
	 */
	public void releaseWifiLock() {
		// 判断是否锁定
		if (mWifiLock.isHeld()) {
			mWifiLock.acquire();
		}
	}

	/**
	 * 得到配置好的网络
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午11:01:30
	 * @return
	 */
	public List<WifiConfiguration> getConfiguration() {
		return mWifiConfigurationList;
	}

	/**
	 * 得到网络列表
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午11:02:10
	 * @return
	 */
	public List<ScanResult> getWifiList() {
		return mWifiList;
	}

	/**
	 * 获得Mac地址
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午11:02:29
	 * @return
	 */
	public String getMacAddress() {
		return (mWifiInfo == null) ? "NULL" : mWifiInfo.getMacAddress();
	}

	/**
	 * 获得BSSID
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午11:02:44
	 * @return
	 */
	public String getBSSID() {
		return (mWifiInfo == null) ? "NULL" : mWifiInfo.getBSSID();
	}

	/**
	 * 获得IP地址
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午11:03:03
	 * @return
	 */
	public String getIpAddress() {
		// return (mWifiInfo == null) ? "127.0.0.1" :
		// Formatter.formatIpAddress(mWifiInfo
		// .getIpAddress());
		if (mWifiInfo == null) {
			return "127.0.0.1";
		} else if (mWifiInfo.getIpAddress() == 0) {
			return "127.0.0.1";
		} else if (Formatter.formatIpAddress(mWifiInfo.getIpAddress()).equals(
				"192.168.1.")) {
			return "127.0.0.1";
		} else {
			return Formatter.formatIpAddress(mWifiInfo.getIpAddress());
		}
	}

	/**
	 * 得到连接WIFI的ID
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午11:03:18
	 * @return
	 */
	public int getNetWordId() {
		return (mWifiInfo == null) ? 0 : mWifiInfo.getNetworkId();
	}

	/**
	 * 得到mWifiInfo的所有信息
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午11:03:30
	 * @return
	 */
	public String getWifiInfo() {
		return (mWifiInfo == null) ? "NULL" : mWifiInfo.toString();
	}

	/**
	 * 获得信号强度
	 * 
	 * @author ronghao
	 * @data 2012-11-14 下午4:09:32
	 * @return
	 */
	public int getStrength() {
		return (mWifiInfo.getBSSID() == null) ? 0 : WifiManager
				.calculateSignalLevel(mWifiInfo.getRssi(), 5);
	}

	/**
	 * 获得信号速度
	 * 
	 * @author ronghao
	 * @data 2012-11-14 下午4:09:52
	 * @return
	 */
	public int getSpeed() {
		return (mWifiInfo.getBSSID() == null) ? 0 : mWifiInfo.getLinkSpeed();
	}

	/**
	 * 开始扫描网络
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午11:01:54
	 */
	public void startScan() {
		mWifiManager.startScan();
		mWifiList = new ArrayList<ScanResult>();
		// 得到扫描结果
		List<ScanResult> wifiList = mWifiManager.getScanResults();
		if (wifiList == null) {
			return;
		}

		for (ScanResult scanResult : wifiList) {
			// TODO:筛选wifi
			// mWifiList.add(scanResult);
			if (scanResult.SSID.contains(Contants.APP_LOCATION + ":")) {
				mWifiList.add(scanResult);
			}
		}
		// 得到配置好的网络连接
		mWifiConfigurationList = mWifiManager.getConfiguredNetworks();
	}

	/**
	 * 连接WIFI
	 * 
	 * @author ronghao
	 * @data 2012-11-14 下午4:37:30
	 * @param index
	 * @return 1 表示连接成功 0表示连接失败 -1表示添加不到保存wifi -2表示越界
	 */
	public int connetionConfiguration(int index) {
		String SSID = mWifiList.get(index).SSID;
		if (index < mWifiList.size()) {
			for (WifiConfiguration wifiConfiguration : mWifiConfigurationList) {
				if (wifiConfiguration.SSID.equals(SSID)) {
					return connecting(wifiConfiguration);
				}
			}
			WifiConfiguration wifiConfiguration = CreateWifiConfiguration(SSID,
					null, 1);
			if ((wifiConfiguration.networkId = addWifiConfiguration(wifiConfiguration)) == -1) {
				return -1;
			}
			return connecting(wifiConfiguration);
		} else {
			return -2;
		}
	}

	/**
	 * 加入保存的 wifi中
	 * 
	 * @author ronghao
	 * @data 2012-11-14 下午4:43:26
	 * @param wifiConfiguration
	 */
	private int addWifiConfiguration(WifiConfiguration wifiConfiguration) {
		int count = 0;
		int result = -1;
		do {
			count += 1;
			result = mWifiManager.addNetwork(wifiConfiguration);
		} while (result == -1 && count < Contants.COUNTNUM);
		return result;
	}

	/**
	 * 连接中
	 * 
	 * @author ronghao
	 * @data 2012-11-14 下午4:34:35
	 * @param wifiConfiguration
	 * @return
	 */
	private int connecting(WifiConfiguration wifiConfiguration) {
		if (wifiConfiguration == null) {
			return -1;
		}
		// // 判断当前连接的wifi与要连接的wifi是否相同，相同则不连接，不同则断开连接
		// if (mWifiManager.getConnectionInfo() != null) {
		// if (mWifiManager.getConnectionInfo().getSSID()
		// .equals(wifiConfiguration.SSID)) {
		// return 1;
		// } else {
		// mWifiManager.disableNetwork(mWifiManager.getConnectionInfo()
		// .getNetworkId());
		// }
		// }

		Boolean result;
		int count = 0;
		do {
			count += 1;
			result = mWifiManager.enableNetwork(wifiConfiguration.networkId,
					true);
		} while (!result && count < Contants.COUNTNUM);
		if (count == Contants.COUNTNUM) {
			return 0;
		}
		return 1;
	}

	// /**
	// * 添加一个网络并连接
	// *
	// * @author ronghao
	// * @data 2012-11-8 上午11:03:35
	// * @param configuration
	// */
	// public void addNetWork(WifiConfiguration configuration) {
	// int wcgId = mWifiManager.addNetwork(configuration);
	// mWifiManager.enableNetwork(wcgId, true);
	// }

	// private int getWifiConfiguration(int index) {
	// if (mWifiList != null && mWifiList.size() > index) {
	// WifiConfiguration configuration = new WifiConfiguration();
	// configuration.SSID = mWifiList.get(index).SSID;
	// int result;
	// do {
	// result = mWifiManager.addNetwork(configuration);
	// } while (result == -1);
	// return result;
	// }
	// return -2;
	// }
	//
	// private int getWifiConfiguration(String ssid) {
	// WifiConfiguration configuration = CreateWifiInfo(ssid, null, 1);
	// addWifiConfiguration(configuration);
	// return result;
	// }

	/**
	 * 断开指定ID的网络
	 * 
	 * @author ronghao
	 * @data 2012-11-8 上午11:03:42
	 * @param netId
	 */
	public void disConnectionWifi(int netId) {
		mWifiManager.disableNetwork(netId);
		mWifiManager.disconnect();
	}

	/**
	 * 开启AP
	 * 
	 * @author ronghao
	 * @data 2012-11-9 下午3:12:43
	 * @param WIFIAPInfo
	 */
	public int startWifiAP(WifiAPInfo wifiAPInfo) {
		Method method = null;
		try {
			method = mWifiManager.getClass().getMethod("setWifiApEnabled",
					WifiConfiguration.class, boolean.class);
			WifiConfiguration netConfig = new WifiConfiguration();
			// WIFI热点名字
			netConfig.SSID = Contants.APP_LOCATION + ":"
					+ wifiAPInfo.getWifiSSID();
			// 公认的IEEE 802.11认证算法
			netConfig.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.OPEN);
			// 这个组安全协议支持的配置
			netConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
			netConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
			// 这个组密钥管理协议支持的配置
			netConfig.allowedKeyManagement.set(wifiAPInfo.getType());
			// 设置的密码对WPA支持成对地这个配置
			netConfig.allowedPairwiseCiphers
					.set(WifiConfiguration.PairwiseCipher.CCMP);
			netConfig.allowedPairwiseCiphers
					.set(WifiConfiguration.PairwiseCipher.TKIP);
			// 这个套组密码支持的配置
			netConfig.allowedGroupCiphers
					.set(WifiConfiguration.GroupCipher.CCMP);
			netConfig.allowedGroupCiphers
					.set(WifiConfiguration.GroupCipher.TKIP);
			// 密码
			netConfig.preSharedKey = wifiAPInfo.getWifiPassword();

			method.invoke(mWifiManager, netConfig, true);
			return 1;
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
			return Contants.CREATEWIFI_ERROR1;
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			return Contants.CREATEWIFI_ERROR2;
		} catch (InvocationTargetException e) {
			e.printStackTrace();
			return Contants.CREATEWIFI_ERROR3;
		} catch (SecurityException e) {
			e.printStackTrace();
			return Contants.CREATEWIFI_ERROR4;
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
			return Contants.CREATEWIFI_ERROR5;
		}
	}

	/**
	 * 关闭
	 * 
	 * @author ronghao
	 * @data 2012-11-14 下午6:48:30
	 */
	public void closeWifiAP() {
		try {
			Method method = mWifiManager.getClass().getMethod(
					"setWifiApEnabled", WifiConfiguration.class, boolean.class);
			method.invoke(mWifiManager, null, false);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 创建可以保存的WifiConfiguration
	 * 
	 * @author ronghao
	 * @data 2012-11-14 下午4:53:38
	 * @param SSID
	 * @param password
	 * @param Type
	 * @return
	 */
	private WifiConfiguration CreateWifiConfiguration(String SSID,
			String password, int Type) {
		WifiConfiguration config = new WifiConfiguration();
		config.allowedAuthAlgorithms.clear();
		config.allowedGroupCiphers.clear();
		config.allowedKeyManagement.clear();
		config.allowedPairwiseCiphers.clear();
		config.allowedProtocols.clear();
		config.SSID = "\"" + SSID + "\"";

		WifiConfiguration tempConfig = this.IsExsits(SSID);
		if (tempConfig != null) {
			mWifiManager.removeNetwork(tempConfig.networkId);
		}

		// if (mWifiManager.getConnectionInfo().getSSID().equals(SSID)) {
		// return null;
		// }

		if (Type == 1) // WIFICIPHER_NOPASS
		{
			config.wepKeys[0] = "";
			config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
			config.wepTxKeyIndex = 0;
		}
		if (Type == 2) // WIFICIPHER_WEP
		{
			config.hiddenSSID = true;
			config.wepKeys[0] = "\"" + password + "\"";
			config.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.SHARED);
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
			config.allowedGroupCiphers
					.set(WifiConfiguration.GroupCipher.WEP104);
			config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
			config.wepTxKeyIndex = 0;
		}
		if (Type == 3) // WIFICIPHER_WPA
		{
			config.preSharedKey = "\"" + password + "\"";
			config.hiddenSSID = true;
			config.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.OPEN);
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
			config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
			config.allowedPairwiseCiphers
					.set(WifiConfiguration.PairwiseCipher.TKIP);
			// config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
			config.allowedPairwiseCiphers
					.set(WifiConfiguration.PairwiseCipher.CCMP);
			config.status = WifiConfiguration.Status.ENABLED;
		}
		return config;
	}

	/**
	 * 是否已经连接
	 * 
	 * @author ronghao
	 * @data 2012-11-14 下午4:54:20
	 * @param SSID
	 * @return
	 */
	private WifiConfiguration IsExsits(String SSID) {
		List<WifiConfiguration> existingConfigs = mWifiManager
				.getConfiguredNetworks();
		for (WifiConfiguration existingConfig : existingConfigs) {
			if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
				return existingConfig;
			}
		}
		return null;
	}

	/**
	 * 添加用户
	 * 
	 * @author ronghao
	 * @data 2012-11-21 下午8:11:38
	 * @param user
	 */
	public void addUser(User user) {
		if (mUsers.contains(user)) {
			return;
		}
		for (int i = 0; i < mUsers.size(); i++) {
			if (mUsers.get(i).getIp().equals(user.getIp())) {
				return;
			}
		}
		mUsers.add(user);
	}
	
	/**
	 * 删除一个user
	 * @author ronghao
	 * @data 2012-11-29    下午7:28:48
	 * @param user
	 */
	public void deleteUser(User user) {
		if (!mUsers.contains(user)) {
			return;
		}
		for (int i = 0; i < mUsers.size(); i++) {
			if (mUsers.get(i).getIp().equals(user.getIp())) {
				mUsers.remove(i);
			}
		}
		return;
	}
	
	/**
	 * 设置所有用户
	 * @author ronghao
	 * @data 2012-11-28    下午8:36:49
	 * @param mUsers
	 */
	public void setmUsers(List<User> mUsers) {
		this.mUsers = mUsers;
	}

	/**
	 * 获得所有用户
	 * 
	 * @author ronghao
	 * @data 2012-11-21 下午8:11:56
	 * @return
	 */
	public List<User> getUsers() {
		return mUsers;
	}

	/**
	 * 获得本机User
	 * 
	 * @author ronghao
	 * @data 2012-11-22 下午12:05:05
	 * @return
	 */
	public User getLocalUser() {
		return mLocalUser;
	}

	/**
	 * 设置本机属性
	 * 
	 * @author ronghao
	 * @data 2012-11-22 下午12:14:57
	 * @param user
	 */
	public void setLocalUser() {
		mLocalUser.setName(sp.getString(Contants.COMMUNICATION_USER_NAME, "0"));
		mLocalUser.setPic(sp.getInt(Contants.COMMUNICATION_USER_PIC, 0));
		mLocalUser.setStyle(sp.getInt(Contants.COMMUNICATION_USER_STYLE, 0));
		mLocalUser.setIp(sp.getString(Contants.COMMUNICATION_USER_IP,
				"127.0.0.1"));
	}

	/**
	 * 更新IP
	 * 
	 * @author ronghao
	 * @data 2012-11-28 上午9:22:33
	 */
	public void updateIP() {
		mLocalUser.setIp(getIpAddress());
		Editor editor = sp.edit();
		editor.putString(Contants.COMMUNICATION_USER_IP, getIpAddress());
		editor.commit();
	}
}